package manager


import activity.InfoActivity
import activity.MainActivity
import activity.ScanActivity
import activity.SettingActivity
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Typeface
import android.view.inputmethod.InputMethodManager
import androidx.core.content.res.ResourcesCompat
import app.App
import app.AppContext
import com.hontech.pizzav2.R
import db.Cargo
import db.Order
import db.Wares
import ext.log
import ext.toMacAddress
import serialport.DeliverPortManager
import serialport.MDBPortManager
import service.ResetService
import task.RefreshSellTask
import task.UpdateStatusTask
import task.debug.PostLogTask
import utils.DeviceInfo
import java.io.PrintWriter
import java.net.NetworkInterface
import java.util.*

const val LOCATION_US = 0
const val LOCATION_UK = 1
const val LOCATION_CA = 2

const val MY_LOCATION = LOCATION_US

object AppManager : Runnable {

    private const val DEFAULT_MAC = "00:18:05:0c:53:cf"

    private const val NEW_URL = "http://admin.lbxrobotics.com:8080/usa-api"

/*    const val TEST_SERVER_URL = "http://test.hontech-rdcenter.com:8080/bg-uc"
    const val SERVER_URL = "http://hfrd.hontech-rdcenter.com:8080/hontechgroup"*/

    const val TEST_SERVER_URL = NEW_URL
    const val SERVER_URL = NEW_URL

    private const val WEB_APP_URL = "http://connectlbx.com"

    private const val DEFAULT_URL = TEST_SERVER_URL

    val InBox710 = android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.N_MR1
    val InBox310 = android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.JELLY_BEAN_MR1

    val PORT1 = if (InBox710) "/dev/ttyO2" else if (InBox310) "/dev/ttymxc1" else "not find "
    val PORT2 = if (InBox710) "/dev/ttyO3" else if (InBox310) "/dev/ttymxc2" else "not find "
    val PORT3 = if (InBox710) "/dev/ttyO4" else if (InBox310) "/dev/ttymxc3" else "not find "

    const val DAY_TIME = 1000 * 60 * 60 * 24

    private const val DELIVER_PORT_KEY = "deliver.port.key"
    private const val ADVERTISING_KEY = "advertising.key"
    private const val SERVER_URL_KEY = "serve-r-.key"
    private const val MDB_PORT_KEY = "mdb.port.key"

    private val DELIVER_PORT_DEFAULT_NAME = PORT2

    private val MDB_PORT_DEFAULT_NAME = PORT1

    val imm = AppContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

    private val sharedPreferences = AppContext.getSharedPreferences(
        "sp.inventory",
        Context.MODE_PRIVATE
    )

    val Version = AppContext.packageManager.getPackageInfo(AppContext.packageName, 0).versionName
    var McuSoftVersion = 0x00

    var isBusy = false

    const val baseUrl = DEFAULT_URL /*sharedPreferences.getString(SERVER_URL_KEY, DEFAULT_URL)!!
        set(value) {
            if (value != field) {
                field = value
                sharedPreferences.edit().putString(SERVER_URL_KEY, value).apply()
            }
        }*/

    var advertising = sharedPreferences.getString(ADVERTISING_KEY, "")!! // 广告缓存
        set(value) {
            if (value != field) {
                field = value
                sharedPreferences.edit().putString(ADVERTISING_KEY, value).apply()
            }
        }

    var deliverPortName = sharedPreferences.getString(DELIVER_PORT_KEY, DELIVER_PORT_DEFAULT_NAME)!!
        set(value) {
            if (value != field) {
                field = value
                sharedPreferences.edit().putString(DELIVER_PORT_KEY, value).apply()
            }
        }

    var mdbPortName = sharedPreferences.getString(MDB_PORT_KEY, MDB_PORT_DEFAULT_NAME)!!
        set(value) {
            if (value != field) {
                field = value
                sharedPreferences.edit().putString(MDB_PORT_KEY, value).apply()
            }
        }

    val MacAddress = getLocalEthernetMacAddress() // "00:18:05:0c:53:75"//
    val MacAddressTopic = MacAddress.replace(":", "")
    val WebAppReqTopic = "$MacAddressTopic-Req"
    var MachCode = ""


    init {
        log(baseUrl, "服务器地址")
        log(mdbPortName, "MDB串口")
        log(deliverPortName, "出货串口")
        log(MacAddress, "MAC地址")
        log(DeviceInfo.info, "设备信息")
        PostLogTask.send("设备开机")
    }

    fun getWebAppQrUrl(): String {
        return "$WEB_APP_URL?topic=$WebAppReqTopic"
    }

    private fun getLocalEthernetMacAddress(): String {
        try {
            val interfaces = NetworkInterface.getNetworkInterfaces()
            interfaces.iterator().forEach {
                if (it.name == "eth0") {
                    return it.hardwareAddress.toMacAddress()
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return DEFAULT_MAC
    }

    fun initApp() {
        AsyncTask.post {

            Wares.createTable() // 创建商品表
            Cargo.createTable() // 创建货道表
            Order.createTable() // 创建订单表

            WaresManager.reloadWithDatabseOrServer()
            StatusManager.Signal = 0
            ReportManager.tryUpdate()
            AsyncTask.post(RefreshSellTask())
            AsyncTask.post(CpuManager)
            AsyncTask.post(this)
            HeatManager.refreshAsync()
            TempValueManager.refreshAsync()
            AdvertisingManager.refreshWithAsync()
            DeliverPortManager.start()
            MDBPortManager.start()
            MQTTManager.connectToServer()
            setResetSystem()
        }
    }

    override fun run() {
        try {
            val content = StatusManager.toJsonWith3("888")
            log(content, "开机上传数据")
            val ret = NetworkManager.update3StatusToServer(content)
            log("---$ret", "开机上传数据返回")
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        AsyncTask.postDelayed(UpdateStatusTask(), 3 * 60 * 1000)
    }

    fun grantPermission(name: String): Boolean {
        log("获取权限:$name")
        val runtime = Runtime.getRuntime()
            .exec("su")
        val pw = PrintWriter(runtime.outputStream)
        pw.write("pm grant ${App.PROCESS} $name")
        pw.flush()
        pw.close()
        val v = runtime.waitFor()
        return v == 0
    }

    fun checkAndGrantPermission(name: String): Boolean {
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
            return true
        }
        val ret = AppContext.checkSelfPermission(name)
        if (ret == PackageManager.PERMISSION_GRANTED) {
            log("已经授权:$name")
            return true
        }
        return grantPermission(name)
    }

    fun resetSystem() {
        val s = arrayOf("su", "-c", "reboot")

        try {
            Runtime.getRuntime().exec(s).waitFor()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun installApk(path: String) {

        log("开始安装:$path")

        val prcess = Runtime.getRuntime().exec("su")
        val pw = PrintWriter(prcess.outputStream)
        pw.println("pm install -r $path")
        pw.flush()
        pw.close()
        val v = prcess.waitFor()
        log("安装返回值:$v")
    }

    fun checkApplication() {
        val msg =
            "Main:${MainActivity.isShow},Set:${SettingActivity.isShow},Scan:${ScanActivity.isShow},Info:${InfoActivity.isShow}"
        log(msg, "检测app状态")
        if ((!MainActivity.isShow) && (!SettingActivity.isShow) && (!ScanActivity.isShow) && (!InfoActivity.isShow)) {
            resetApp()
            return
        }
    }

    fun resetApp() {
        log("开始重启App")

        val i = Intent(AppContext, MainActivity::class.java)
        i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        val pi = PendingIntent.getActivity(AppContext, 0, i, 0)
        val am = AppContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager

        am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 500, pi)

        android.os.Process.killProcess(android.os.Process.myPid())
    }

    fun setResetSystem() {
        val target = Calendar.getInstance()
        target.set(Calendar.HOUR_OF_DAY, 3)
        target.set(Calendar.MINUTE, 0)
        target.set(Calendar.SECOND, 0)
        val targetTime = target.timeInMillis

        val currentTime = Calendar.getInstance().timeInMillis
        val am = AppContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val intent = Intent(AppContext, ResetService::class.java)
        val pi = PendingIntent.getService(AppContext, 0, intent, 0)

        val resetTime = if (targetTime > currentTime) targetTime else targetTime + DAY_TIME
        log("重启时间：$resetTime")

        am.set(AlarmManager.RTC_WAKEUP, resetTime, pi)
    }

}
